#include <sys/unistd.h>
#include "StreamerDownloadOnlineFile.h"
#include "Protocol/ProtocolApi.h"
#include "log.h"


namespace Media{

    std::map<FileDownloadType, Media::StreamerDownloadOnlineFile::Ptr> StreamerDownloadOnlineFile::sm_instance;
    std::mutex StreamerDownloadOnlineFile::sm_instanceLock; 
    

    StreamerDownloadOnlineFile::~StreamerDownloadOnlineFile(){

    }

    bool StreamerDownloadOnlineFile::start(std::vector<std::string> urls, downloadCb cb, std::string path){
        m_urls = urls;
        m_downloadCallback = cb;
        m_savePath = path;
        //设置停止标志位
        m_stopLoad.store(false);
        //调用下载接口开始下载文件
        downloadUrls();
        return true;
    }

    bool StreamerDownloadOnlineFile::stop(){
        //设置停止标志
        m_stopLoad.store(true);
        while(m_downloadRunning.load()){
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        return true;
    }

    bool StreamerDownloadOnlineFile::downloadUrls(){
        //判断当前给的路径是否可以访问
        if(m_downloadCallback == nullptr){
            LOG_PrintError("m_downloadCallback is empty\n");
            return false;
        }
        
        m_downloadRunning.store(true);
        //遍历urls，逐个下载文件
        for(const auto& url : m_urls)
        {
            //判断当前下载是否停止，不停止则继续
            if(m_stopLoad.load()){
                break;
            }
            //最大下载次数
            int maxDownNum = 5;
            //确定下载本次文件的各个参数包括下载回调，保存保存路径（文件描述符），url，下载进度， 停止回调,除此之外还需要保证当前下载时阻塞的这就需要回调捕获一个标志判断
            std::string fileName;
            // 从url中提取文件名
            size_t lastSlash = url.find_last_of('/');
            if (lastSlash != std::string::npos) {
                // 提取文件名
                fileName = url.substr(lastSlash + 1);
            } else {
                m_downloadCallback(false, url, fileName);
                LOG_PrintWarn("cannot to parse url: %s\n", url.c_str());
                continue;
            }
            std::string savePath = m_savePath + fileName;
            LOG_PrintWarn("savePath ----------------------- %s\n", savePath.c_str());
            LOG_PrintWarn("current url ----------------- %s\n", url.c_str());

            int done_ret = -1;
            auto resultCb = [url, &done_ret, savePath, this](const Fdt::SockException &ex){
                bool result = false;
                if (ex) {
                    WarnL << "network err:" << ex.getErrCode() << " " << ex.what();
                    done_ret = 1;
                } else {
                    WarnL << "succeed"  << ex.what();
                    result = true;
                    done_ret = 0;
                }
                m_downloadCallback(result, url, savePath);
            };
            int down_progress = 0;

            std::function<void (void)> stop_func; //主动停止回调该函数

            do
            {   
                maxDownNum--;
                done_ret = -1;
                //开始下载
                Protocol::IProtocolInterface::GetInstance()->HttpDownloadFile(url, savePath, resultCb, down_progress, stop_func);

                //循环等待当前下载结束，这里需要判断停止下载标志位（注意线程安全）
                while(done_ret < 0){
                    if(m_stopLoad.load()){
                        stop_func();
                        break;
                    }
                    std::this_thread::sleep_for(std::chrono::seconds(1));
                }

            }while(done_ret == 1 && !m_stopLoad.load() && maxDownNum > 0);
            
        }
        LOG_PrintWarn("StreamerDownloadOnlineFile::downloadUrls()\n");
        m_downloadRunning.store(false);
        return true;
    }

}